/**
 * @author Liu Cong
 */

(function(){

/**
 * This is the default Implementation of Message, which provides
 * a convenient base for behavior and association of common endpoints
 *
 * @package    FireAMF
 */
FireAMF.Message = function(){};

FireAMF.Message.prototype = {
    /**
     * generate a unique id
     *
     * Format is: ########-####-####-####-############
     * Where # is an uppercase letter or number
     * example: 6D9DC7EC-A273-83A9-ABE3-00005FD752D6
     *
     * @return string
     */
    generateId: function() {
		return (format(mt_rand().toString(16), 8) + '-'
			+ format(mt_rand(0, 65535).toString(16), 4) + '-'
			+ format((mt_rand(0, 65535) & 0xffe1 | 0x4), 4) + '-'
			+ format((mt_rand(0, 255) & 0xf9 | 0x2), 2) + format(mt_rand(0, 255), 2) + '-'
			+ format(mt_rand(), 12)).toUpperCase();
    },
	toString: function(){
		var headers = [h+': '+this.headers[h] for(h in this.headers)].join(',\n');
		var body = [b+': '+this.body[b] for(b in this.body)].join(',\n');
		return '{\n'
			+ 'clientId: '+this.clientId+',\n'
			+ 'destination: '+this.destination+',\n'
			+ 'messageId: '+this.messageId+',\n'
			+ 'timestamp: '+this.timestamp+',\n'
			+ 'timeToLive: '+this.timeToLive+',\n'
			+ 'headers: {\n'+headers+'\n},\n'
			+ 'body: {\n'+body+'\n}\n}';
	}
};

function mt_rand(min, max){
	if(undefined === min) min = 0;
	if(undefined === max) max = 0x7fffffff;
	return Math.floor(Math.random()*(max-min))+min;
}

function format(num, length){
	var str = num.toString(16);
	while(str.length<length){
		str = '0'+str;
	}
	return str;
}

/**
 * This type of message contains information needed to perform
 * a Remoting invocation.
 *
 * Corresponds to flex.messaging.messages.RemotingMessage
 *
 * @package    FireAMF
 */
FireAMF.RemotingMessage = function(){
    this.clientId    = this.generateId();
    this.destination = null;
    this.messageId   = this.generateId();
    this.timestamp   = Date.now()+'00';
    this.timeToLive  = 0;
    this.headers     = new Object();
    this.body        = null;
};

FireAMF.RemotingMessage.prototype = new FireAMF.Message();

/**
 * This is the type of message returned by the MessageBroker
 * to endpoints after the broker has routed an endpoint's message
 * to a service.
 *
 * flex.messaging.messages.AcknowledgeMessage
 *
 * @package    FireAMF
 */
FireAMF.AcknowledgeMessage = function(){};

FireAMF.AcknowledgeMessage.prototype = new FireAMF.Message();

/**
 * This type of message contains information necessary to perform
 * point-to-point or publish-subscribe messaging.
 *
 * @package    FireAMF
 */
FireAMF.AsyncMessage = function(){};

FireAMF.AsyncMessage.prototype = new FireAMF.Message();

/**
 * A message that represents an infrastructure command passed between
 * client and server. Subscribe/unsubscribe operations result in
 * CommandMessage transmissions, as do polling operations.
 *
 * Corresponds to flex.messaging.messages.CommandMessage
 *
 * Note: THESE VALUES MUST BE THE SAME ON CLIENT AND SERVER
 *
 * @package    FireAMF
 */
FireAMF.CommandMessage = function(){};

FireAMF.CommandMessage.prototype = new FireAMF.Message();

/**
 * Creates the error message to report to flex the issue with the call
 *
 * Corresponds to flex.messaging.messages.ErrorMessage
 *
 * @package    FireAMF
 */
FireAMF.ErrorMessage = function(){};

FireAMF.ErrorMessage.prototype = new FireAMF.Message();

})();
